/**
 * 
 */
package view;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Observable;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

import listeners.AddListener;
import listeners.DeleteSelListener;
import listeners.LoadListener;
import listeners.SaveListener;
import listeners.SerializationListener;
import model.ModelShop;
import verifiers.NameVerifier;
import verifiers.PriceVerifier;
import verifiers.QuantityVerifier;
import example.ListProductRenderer;
import fpt.com.Product;

public class ViewShop extends JFrame implements java.util.Observer {

	private static final long serialVersionUID = -4700812464583735087L;

	private Container contentPane;
	private JList<Product> list;
	private JScrollPane scrollPane;
	private Container inputContainer;
	private JTextPane inputName;
	private JTextPane inputPrice;
	private JTextPane inputQuant;
	private JButton buttonAdd;
	private JButton buttonDelSel;
	private NameVerifier nameVerifier;
	private PriceVerifier priceVerifier;
	private QuantityVerifier quantVerifier;
	private JMenu mSerializable;
	private JMenu mLoadSave;
	private JMenuBar mbar;
	private JMenuItem miNone;
	private JMenuItem miBin;
	private JMenuItem miBeans;
	private JMenuItem miXstream;
	private JMenuItem miOpenJPA;
	private JMenuItem miLoad;
	private JMenuItem miSave;

	public ViewShop() {
		super("ViewShop Gruppe 11");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null); // Fenster zentrieren

		contentPane = this.getContentPane();
		contentPane.setLayout(new BorderLayout());

		// Menü: Auswahl der Strategie
		miNone = new JMenuItem("None");
		miNone.setName("none");
		miBin = new JMenuItem("Bin");
		miBin.setName("binary");
		miBeans = new JMenuItem("Beans");
		miBeans.setName("beans");
		miXstream = new JMenuItem("XStream");
		miXstream.setName("xstream");
		miOpenJPA = new JMenuItem("OpenJPA");
		miOpenJPA.setName("openjpa");
		miLoad = new JMenuItem("Load");
		miSave = new JMenuItem("Save");
		mSerializable = new JMenu("Serializable");
		mLoadSave = new JMenu("Load/Save");
		mbar = new JMenuBar();
		mSerializable.add(miNone);
		mSerializable.add(miBin);
		mSerializable.add(miBeans);
		mSerializable.add(miXstream);
		mSerializable.add(miOpenJPA);
		mLoadSave.add(miLoad);
		mLoadSave.add(miSave);
		mbar.add(mSerializable);
		mbar.add(mLoadSave);
		this.setJMenuBar(mbar);

		// Disable Load/Save Menu zu Beginn, da standardmäßig
		// keine Serialisierung ausgewählt ist
		mLoadSave.setEnabled(false);

		// Ausgabebereich: Produktliste
		list = new JList<>();
		list.setCellRenderer(new ListProductRenderer());
		scrollPane = new JScrollPane(list);

		// Eingabebereich
		inputContainer = new Container();
		inputContainer
				.setLayout(new BoxLayout(inputContainer, BoxLayout.Y_AXIS));
		inputName = new JTextPane();
		inputPrice = new JTextPane();
		inputQuant = new JTextPane();
		buttonAdd = new JButton("add");
		buttonDelSel = new JButton("delete selected");
		inputContainer.add(inputName);
		inputContainer.add(inputPrice);
		inputContainer.add(inputQuant);
		inputContainer.add(buttonAdd);
		inputContainer.add(buttonDelSel);

		inputName.setBorder(BorderFactory.createTitledBorder("Name"));
		inputPrice.setBorder(BorderFactory.createTitledBorder("Price"));
		inputQuant.setBorder(BorderFactory.createTitledBorder("Quantity"));

		contentPane.add(scrollPane, BorderLayout.CENTER);
		contentPane.add(inputContainer, BorderLayout.EAST);

		// Prüfung der Eingaben auf Korrektheit
		nameVerifier = new NameVerifier();
		priceVerifier = new PriceVerifier();
		quantVerifier = new QuantityVerifier();

		inputName.setInputVerifier(nameVerifier);
		inputPrice.setInputVerifier(priceVerifier);
		inputQuant.setInputVerifier(quantVerifier);

		this.pack();
		this.setVisible(true);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		list.setListData(((ModelShop) arg0).getProductArray());
	}

	// Listener, der nur für die Delete-Aktion zuständig ist
	// Interface wird in Controller implementiert
	public void addDeleteSelListener(final DeleteSelListener delSelListener) {
		buttonDelSel.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				delSelListener.deleteSel();
			}

		});

	}

	// Listener, der nur für die Add-Aktion zuständig ist
	// Interface wird in Controller implementiert
	public void addAddListener(final AddListener addListener) {
		buttonAdd.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				if (nameVerifier.verify(inputName)
						&& priceVerifier.verify(inputPrice)
						&& quantVerifier.verify(inputQuant)) {
					addListener.add(inputName.getText(),
							Double.parseDouble(inputPrice.getText()),
							Integer.parseInt(inputQuant.getText()));
				}
			}
		});

	}

	// Listener, der dazu dient, Serialisierung auszuwählen
	// Interface wird in Controller implementiert
	public void addSerializationListener(
			final SerializationListener serializationListener) {

		ActionListener serListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				serializationListener.chooseSerialization(((JMenuItem) e
						.getSource()).getName());

			}
		};

		miNone.addActionListener(serListener);
		miBeans.addActionListener(serListener);
		miBin.addActionListener(serListener);
		miXstream.addActionListener(serListener);
		miOpenJPA.addActionListener(serListener);

	}

	// Listener, der nur für die Load-Aktion zuständig ist
	// Interface wird in Controller implementiert
	public void addLoadListener(final LoadListener loadListener) {
		miLoad.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				loadListener.load();
			}

		});

	}

	// Listener, der nur für die Save-Aktion zuständig ist
	// Interface wird in Controller implementiert
	public void addSaveListener(final SaveListener saveListener) {
		miSave.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				saveListener.save();
			}

		});

	}

	// Gibt ausgewählte Produkte zurück
	public List<Product> getSelected() {
		return list.getSelectedValuesList();
	}

	// Enable / Disable Load/Save-Menu
	// Kann z.B. deaktiviert werden, wenn keine Serialisierung gewählt wurde
	public void activateLoadSave(boolean b) {
		mLoadSave.setEnabled(b);

	}

}
